package com.woniu.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.woniu.shop.constant.RedisConstant;
import com.woniu.shop.entity.dto.ShowShopIncomeDTO;
import com.woniu.shop.entity.vo.ShopIncomeVO;
import com.woniu.shop.pojo.Shop;
import com.woniu.shop.pojo.ShopIncome;
import com.woniu.shop.mapper.ShopIncomeMapper;
import com.woniu.shop.pojo.ShopIncome;
import com.woniu.shop.pojo.ShopYearIncome;
import com.woniu.shop.service.IShopIncomeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 门店收益表 服务实现类
 * </p>
 *
 * @author LiFangyu
 * @since 2023-02-15
 */
@Service
@Slf4j
public class ShopIncomeServiceImpl extends ServiceImpl<ShopIncomeMapper, ShopIncome> implements IShopIncomeService {

    @Autowired(required = false)
    private ShopIncomeMapper shopIncomeMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public ShopIncomeVO showShopIncome(ShowShopIncomeDTO showShopIncomeDTO){
        // 1.查询总收益
        LambdaQueryWrapper<ShopIncome> incomesWrapper = new LambdaQueryWrapper<>();
        incomesWrapper.eq(!StringUtils.isEmpty(showShopIncomeDTO.getShopId()), ShopIncome::getShopId, showShopIncomeDTO.getShopId());
        List<ShopIncome> incomesAll = shopIncomeMapper.selectList(incomesWrapper);
        BigDecimal allAmount = new BigDecimal(0);
        BigDecimal thisYear = new BigDecimal(0);
        BigDecimal thisMonth = new BigDecimal(0);
        BigDecimal today = new BigDecimal(0);
        BigDecimal condition = new BigDecimal(0);
        for (ShopIncome shopIncome : incomesAll) {
            allAmount = allAmount.add(shopIncome.getAmount());
            // 2.查询本年收益
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(shopIncome.getCreatedTime());
            int incomeYear = calendar.get(Calendar.YEAR);
            int incomeMonth = calendar.get(Calendar.MONTH);
            int incomeDay = calendar.get(Calendar.DAY_OF_MONTH);
            Date currentDate = new Date();
            SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
            SimpleDateFormat monthFormat = new SimpleDateFormat("M");
            SimpleDateFormat dayFormat = new SimpleDateFormat("d");
            if(incomeYear == Integer.parseInt(yearFormat.format(currentDate))){
                thisYear = thisYear.add(shopIncome.getAmount());
            }
            // 3.查询本月收益
            if(incomeYear == Integer.parseInt(yearFormat.format(currentDate)) && incomeMonth + 1 == Integer.parseInt(monthFormat.format(currentDate))){
                thisMonth = thisMonth.add(shopIncome.getAmount());
            }
            // 4.查询今日收益
            if(incomeYear == Integer.parseInt(yearFormat.format(currentDate)) && incomeMonth + 1 == Integer.parseInt(monthFormat.format(currentDate)) && incomeDay == Integer.parseInt(dayFormat.format(currentDate))){
                today = today.add(shopIncome.getAmount());
            }
        }
        // 5.条件查询收益
        // 5.1如果不是查询某年份，按开始时间和结束时间查询
        List<ShopIncome> incomesInDate = null;
        List<ShopIncome> list = null;
        if(StringUtils.isEmpty(showShopIncomeDTO.getYear())){
            LambdaQueryWrapper<ShopIncome> conditionWrapper = new LambdaQueryWrapper<>();
            conditionWrapper.eq(!StringUtils.isEmpty(showShopIncomeDTO.getShopId()), ShopIncome::getShopId, showShopIncomeDTO.getShopId());
            conditionWrapper.ge(!StringUtils.isEmpty(showShopIncomeDTO.getBegin()), ShopIncome::getCreatedTime, showShopIncomeDTO.getBegin());
            conditionWrapper.le(!StringUtils.isEmpty(showShopIncomeDTO.getEnd()), ShopIncome::getCreatedTime, showShopIncomeDTO.getEnd());
            incomesInDate = shopIncomeMapper.selectList(conditionWrapper);
            for (ShopIncome shopIncome : incomesInDate) {
                condition = condition.add(shopIncome.getAmount());
            }
        }else {
            //5.2如果是查询某年份，从年份收益表中查询(Redis/数据库)
            String redisData = (String) stringRedisTemplate.opsForHash().get(RedisConstant.SHOP_YEAR_INCOME_AMOUNT.name() + "_" + showShopIncomeDTO.getShopId(), showShopIncomeDTO.getYear());
            if(StringUtils.isEmpty(redisData)){
                BigDecimal sqlData = shopIncomeMapper.selectShopIncomeInYear(showShopIncomeDTO.getShopId(), showShopIncomeDTO.getYear());
                condition = condition.add(sqlData);
                // 将数据库查询出来的数据保存到redis
                ObjectMapper objectMapper = new ObjectMapper();
                String jackson = null;
                try {
                    jackson = objectMapper.writeValueAsString(sqlData);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                    log.error("json写入异常，异常的内容为{}",sqlData);
                }
                stringRedisTemplate.opsForHash().put(RedisConstant.SHOP_YEAR_INCOME_AMOUNT.name() + "_" + showShopIncomeDTO.getShopId(), showShopIncomeDTO.getYear(), jackson);
            }else {
                condition = condition.add(new BigDecimal(redisData));
            }

            String incomeListData = (String) stringRedisTemplate.opsForHash().get(RedisConstant.SHOP_YEAR_INCOME_LIST.name() + "_" + showShopIncomeDTO.getShopId(), showShopIncomeDTO.getYear());
            ObjectMapper objectMapper = new ObjectMapper();
            //list = objectMapper.readValue(incomeListData, new TypeReference<List<ShopIncome>>() {});
            assert incomeListData != null;
            JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, ShopIncome.class);
            try {
                list = objectMapper.readValue(incomeListData, javaType);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                log.error("json反序列化异常，异常的内容为{}",incomeListData);
            }
            if(list == null){
                LambdaQueryWrapper<ShopIncome> redisWrapper = new LambdaQueryWrapper<>();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
                try {
                    redisWrapper.ge(ShopIncome::getCreatedTime,sdf.parse(showShopIncomeDTO.getYear()));
                    String nextYear = String.valueOf(Integer.parseInt(showShopIncomeDTO.getYear()) + 1) ;
                    redisWrapper.le(ShopIncome::getCreatedTime,sdf.parse(nextYear));
                    list = shopIncomeMapper.selectList(redisWrapper);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        // 6.组装数据模型
        ShopIncomeVO shopIncomeVO = new ShopIncomeVO();
        shopIncomeVO.setAllAmount(allAmount);
        shopIncomeVO.setThisYear(thisYear);
        shopIncomeVO.setThisMonth(thisMonth);
        shopIncomeVO.setToday(today);
        shopIncomeVO.setCondition(condition);
        if(StringUtils.isEmpty(showShopIncomeDTO.getYear())){
            if(StringUtils.isEmpty(showShopIncomeDTO.getBegin()) && StringUtils.isEmpty(showShopIncomeDTO.getEnd())){
                shopIncomeVO.setIncomes(incomesAll);
            }else {
                shopIncomeVO.setIncomes(incomesInDate);
            }
        }else {
            shopIncomeVO.setIncomes(list);
        }
        return shopIncomeVO;
    }
}
